package me.ingxin.android.router.utils

import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import androidx.collection.ArrayMap
import androidx.fragment.app.FragmentActivity
import java.util.*

/**
 * 找到fragmentActivity
 */
internal fun Context.getFragmentActivity(): FragmentActivity? {
    if (this is FragmentActivity) {
        return this
    } else if (this is ContextWrapper) {
        return this.baseContext.getFragmentActivity()
    }
    return null
}

/**
 * 获取uri上携带的参数
 */
internal fun getQuery(rawUri: String): Map<String, String> {
    if (rawUri.isEmpty()) {
        return emptyMap()
    }
    var index = rawUri.indexOf("?")
    var query = if (index != -1) rawUri.substring(index + 1) else rawUri
    index = query.indexOf("#")
    query = if (index != -1) query.substring(0, index) else query

    val paramMap = ArrayMap<String, String>()
    var start = 0
    do {
        val next = query.indexOf('&', start)
        val end = if (next == -1) query.length else next

        var separator = query.indexOf('=', start)
        if (separator > end || separator == -1) {
            separator = end
        }

        val name = query.substring(start, separator)

        if (name.isNotEmpty()) {
            val value = if (separator == end) "" else query.substring(separator + 1, end)
            paramMap[name] = value
        }

        // Move start to end of name.
        start = end + 1
    } while (start < query.length)

    return Collections.unmodifiableMap(paramMap)
}

/**
 * 兼容[Intent.getBooleanExtra]方法，增加解析路由uri上携带的字段的能力
 */
fun Intent.getBooleanWrap(name: String, defaultValue: Boolean): Boolean {
    return getWrap(this, name, defaultValue)
}

/**
 * 兼容[Intent.getFloatExtra]方法，增加解析路由uri上携带的字段的能力
 */
fun Intent.getFloatWrap(name: String, defaultValue: Float): Float {
    return getWrap(this, name, defaultValue)
}

/**
 * 兼容[Intent.getDoubleExtra]方法，增加解析路由uri上携带的字段的能力
 */
fun Intent.getDoubleWrap(name: String, defaultValue: Double): Double {
    return getWrap(this, name, defaultValue)
}

/**
 * 兼容[Intent.getLongExtra]方法，增加解析路由uri上携带的字段的能力
 */
fun Intent.getLongWrap(name: String, defaultValue: Long): Long {
    return getWrap(this, name, defaultValue)
}

/**
 * 兼容[Intent.getIntExtra]方法，增加解析路由uri上携带的字段的能力
 */
fun Intent.getIntWrap(name: String, defaultValue: Int): Int {
    return getWrap(this, name, defaultValue)
}

private inline fun <reified T> getWrap(intent: Intent?, name: String, defaultValue: T): T {
    val v = intent?.extras?.get(name) ?: return defaultValue
    if (v is T) {
        return v
    }
    if (v !is String) {
        return defaultValue
    }
    return try {
        when (T::class) {
            Boolean::class -> v.toBoolean() as T
            Float::class -> v.toFloat() as T
            Double::class -> v.toDouble() as T
            Long::class -> v.toLong() as T
            Int::class -> v.toInt() as T
            else -> defaultValue
        }
    } catch (ex: Exception) {
        ex.printStackTrace()
        defaultValue
    }
}